import json,sys

class JSONExtDecoder(json.JSONEncoder):
    def encode(self, obj):
        def hint_tuples(item):
            if isinstance(item, tuple):
                return {'__tuple__': True, 'items': item}
            if isinstance(item, list):
                return [hint_tuples(e) for e in item]
            else:
                return item

        return super(JSONExtDecoder, self).encode(hint_tuples(obj))

def hinted_tuple_hook(obj):
    if '__tuple__' in obj:
        return tuple(obj['items'])
    else:
        return obj

def dump(obj,fp,**kwargs):
    return json.dump(obj,fp,cls=JSONExtDecoder,indent=4,**kwargs)
def load(fp , **kwargs):
    return json.load(fp,object_hook=hinted_tuple_hook,**kwargs)

def dumps(obj,**kwargs):
    return json.dumps(obj,cls=JSONExtDecoder,**kwargs)
def loads(string, **kwargs):
    return json.loads(string,object_hook=hinted_tuple_hook,**kwargs)

import csv
def json_data(s):
    try:
        return loads(s)
    except:
        return s
def csv_reader(fp):
    reader=csv.reader(fp) #header line
    head=next(reader)
    for row in reader:
        yield {c:json_data(d) for c,d in zip(head,row)}
def csv_writer(data,fp):
    assert('fields' in data)
    assert('data' in data)
    writer=csv.writer(fp)
    writer.writerow(data['fields'])
    for row in data['data']:
        w=[d if type(d) is str else dumps(d) for d in row]
        writer.writerow(w)
d='''
    {
    "fields": [
        "id",
        "name",
        "author",
        "description",
        "timestamp",
        "status",
        "wafer",
        "datecode",
        "chip_id",
        "chip_type_id",
        "ticket_id"
    ],
    "data": [ [1,
            "ALI0977,ddd",
            "_NULL_",
            null,
            null,
            "new",
            null,
            null,
            null,
            1,
            1
        ]  ]

}
    '''
def test():
    from io import StringIO
    data=loads(d

    )
    from io import StringIO
    buf=StringIO()
    csv_writer(data,buf)
    print(buf.getvalue())
    buf.seek(0)
    for i in csv_reader(buf):
        print(i)

if __name__ == '__main__':
    import sys
    test()
    sys.exit(0)
    obj=[1, 2, (3, 4), [5, 6, (7, 8)]]
    jsonstring =dumps(obj)
    print(jsonstring)
    # [1, 2, {"items": [3, 4], "__tuple__": true}, [5, 6, {"items": [7, 8], "__tuple__": true}]]
    print(loads(jsonstring))

    # [1, 2, (3, 4), [5, 6, (7, 8)]]
    with open('/tmp/test.json','w') as fp:
        dump(obj,fp,indent=4)
    with open('/tmp/test.json','r') as fp:
        print(load(fp))
